-module(ebbs_board).
-include_lib("stdlib/include/qlc.hrl").
-include_lib("article.hrl").
-compile(export_all).

create_board(Name) ->
    mnesia:create_table(Name,
			[{attributes, record_info(fields, article)},
			 {disc_copies, [node()]},
			 {index, [parent_id, root_id, author_id]},
			 {record_name, article},
			 {type, set}]).

list_boards() ->
    lists:sort(mnesia:system_info(tables) -- [ebbs_user, schema]).

%% internal function to implement post() and reply().
add(Board, ParentId, RootId, AuthorId, AuthorCertSHA1, Title, Content) ->
    Now = ebbs_util:now(),
    Id = erlang:md5(list_to_binary([ParentId, RootId,
				    AuthorId, AuthorCertSHA1,
				    Title, term_to_binary(Now)])),
    Id2 = list_to_binary(ebbs_util:binary_to_hexstring(Id)),
    case RootId of
	<<0>> -> RootId2 = Id2;
	_ -> RootId2 = RootId
    end,
    Article = #article{id = Id2,
		       parent_id = ParentId,
		       root_id = RootId2,
		       author_id = AuthorId,
		       author_cert_sha1 = AuthorCertSHA1,
		       title = Title,
		       content = Content,
		       length = iolist_size(Content),
		       flags = 0,
		       ctime = Now,
		       mtime = Now},
    F = fun () -> mnesia:write(Board, Article, write) end,
    {_, Result} = mnesia:transaction(F),
    Result.

post(Board, AuthorId, AuthorCertSHA1, Title, Content) ->
    ParentId = list_to_binary(ebbs_util:binary_to_hexstring(<<0:128>>)),
    add(Board, ParentId, <<0>>, AuthorId, AuthorCertSHA1, Title, Content).

reply(Board, ParentId, AuthorId, AuthorCertSHA1, Title, Content) ->
    F = fun () ->
		case mnesia:read(Board, ParentId) of
		    [] -> mnesia:abort(parent_not_found);
		    [Parent] -> add(Board, ParentId, Parent#article.root_id,
				    AuthorId, AuthorCertSHA1, Title, Content)
		end
	end,
    {_, Result} = mnesia:transaction(F),
    Result.

update(Board, Id, Title, Content) ->
    F = fun () ->
		case mnesia:wread({Board, Id}) of
		    [] -> mnesia:abort(article_not_found);
		    [Article] ->
			NewArticle = Article#article{title=Title,
						     content=Content,
						     mtime=ebbs_util:now()},
			mnesia:write(Board, NewArticle, write)
		end
	end,
    {_, Result} = mnesia:transaction(F),
    Result.

delete(Board, Id) ->
    F = fun () ->
		mnesia:delete(Board, Id, write)
	end,
    {_, Result} = mnesia:transaction(F),
    Result.

view(Board, Id) ->
    mnesia:dirty_read(Board, Id).

list(Board) ->
    F = fun () ->
		QH = qlc:q([Article || Article <- mnesia:table(Board)]),
		QH2 = qlc:keysort(11, QH),      % sort by ctime
		qlc:e(QH2)
	end,
    {atomic, Articles} = mnesia:transaction(F),
    Articles.

clear(Board) ->
    {_, Result} = mnesia:clear_table(Board),
    Result.

